home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacWorld 1998 September
/
Macworld (1998-09).dmg
/
Shareware World
/
Info
/
For Developers
/
MacZoop 1.8.3
/
More Classes
/
Threads
/
ZThread.h
< prev
next >
Wrap
Text File
|
1996-11-26
|
4KB
|
145 lines
/*************************************************************************************************
*
*
* ObjectMacZapp -- a standard Mac OOP application template
*
*
*
* ZThread.h -- an object that implements a single thread of execution.
*
*
*
*
*
* © 1996, Graham Cox
*
*
*
*
*************************************************************************************************/
#pragma once
#ifndef __ZTHREAD__
#define __ZTHREAD__
#pragma options align=native
#include <Threads.h>
#include "ZErrors.h"
class ZThread
{
protected:
Boolean fDone;
ThreadID itsID;
Size itsStack;
long itsPeriod;
public:
ZThread( long doPeriod = 0, Size stackSize = 0 ); // Constructor
virtual ~ZThread(); // Destructor
// Do() is called by ThreadEntry() every doPeriod ticks. This is the default
// behaviour for a thread. If you want something more complex, override ThreadEntry()
virtual void Do() {};
// ThreadEntry is the general entry point for the thread. You should only override
// this if you don't want to use the default behaviour of calling Do()
// periodically (e.g. async I/O perhaps).
//
// If you do override ThreadEntry() you must call one of the Yield functions
// every so often to let all the other threads get a look in.
virtual void ThreadEntry();
// SwitchingIn is called just before your thread is switched in to allow
// you to perform additional context setup (e.g. GrafPorts)
virtual void SwitchingIn() {};
// SwitchingOut is called just before your thread is switched out to allow
// you to save extra context data.
virtual void SwitchingOut() {};
// IsDone decides whether or not you have finished. By default this
// returns fDone.
//
// This is used to exit the loop that keeps calling Do() - when IsDone returns
// TRUE, the thread will finish and terminate.
virtual inline Boolean IsDone();
// SetDoPeriod() allows you to adjust the interval that Do() is called at
void SetDoPeriod( long doPeriod = 0 );
// Start() actually creates the thread and sets it running
virtual void Start();
// Stop() stops a thread. It can be restarted with Restart()
virtual OSErr Stop();
// Restart() puts a thread into the Ready state, restarting it after a Stop()
virtual OSErr Restart();
// Terminate() kills a thread
virtual void Terminate( Boolean fReturnToPool = FALSE );
// GetState() returns current thread state in *pState
// The states are defined in Threads.h but can be a bit confusing.
//
// Basically my understanding is:
//
// - kReadyThreadState means that the thread is ready to run but is not the current
// thread. Normal running threads will return this if GetState() is called from
// another thread.
//
// - kStoppedThreadState means that the thread has been stopped by a Stop() instruction.
//
// - kRunningThreadState means that the thread is running *and* is the current thread.
// GetState() will return this if it's called from within Do() say.
//
ThreadState GetState();
// Returns thread ID
inline ThreadID GetThreadID()
{
return itsID;
}
// Returns available stack space in *freeStack
void GetStackSpace( unsigned long *freeStack )
{
FailOSErr( ThreadCurrentStackSpace( itsID, freeStack) );
}
// Sleep for ticksToSleep ticks
virtual void SleepTicks( long ticksToSleep );
};
// ThreadEntryGlue is required because you can't pass a pointer to a virtual member
// function to NewThread - calling a member function implicitly passes a pointer to
// the object + a virtual function cannot be declared as pascal.
//
// Instead, NewThread gets a pointer to ThreadEntryGlue and ThreadEntryGlue calls
// ThreadEntry in the object. This is possible because ThreadEntryGlue gets a pointer
// to the object as its parameter (otherwise it wouldn't know which object to call!
pascal void * ThreadEntryGlue( ZThread* me );
// SwitchingInGlue() and SwitchingOutGlue() are needed for similar reasons to above.
pascal void SwitchingInGlue( ThreadID threadBeingSwitched, ZThread* me );
pascal void SwitchingOutGlue( ThreadID threadBeingSwitched, ZThread* me );
// Utility function - yield for lTicks ticks
void YieldTicks( long lTicks );
// Utility function - safe yield
void SafeYield();
#pragma options align=reset
#endif